package com.alvin.demo.common.config;

import com.alvin.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;

import javax.servlet.http.HttpSession;
import javax.sql.DataSource;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {

	@Autowired
	private UserService userService;

	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	// SpringSecurity配置信息
	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(
				requests -> requests.antMatchers(
						// 允许不登录就能访问
						"/", "/failer", "/statics/**" ,"/error/**" , "/favicon.ico").permitAll().anyRequest()
                .authenticated())
					.formLogin(login -> login.loginPage("/").loginProcessingUrl("/login")
                .successHandler(authenticationSuccessHandler())
							.failureHandler(authenticationFailureHandler())).logout(logout -> logout.invalidateHttpSession(true).logoutSuccessUrl("/")).rememberMe(me -> me
                .alwaysRemember(false).useSecureCookie(true).userDetailsService(userService)
                .tokenValiditySeconds(30 * 24 * 60 * 60) // 记住我令牌有效期30天
                .tokenRepository(jdbcTokenRepository())).csrf(AbstractHttpConfigurer::disable);
		return http.build();
	}

	@Autowired
	private DataSource dataSource;

	@Bean
	public JdbcTokenRepositoryImpl jdbcTokenRepository() {
		JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
		jdbcTokenRepository.setDataSource(dataSource);
		// 是否启动时自动创建表，第一次启动创建就行，后面启动把这个注释掉,不然报错已存在表
//        jdbcTokenRepository.setCreateTableOnStartup(true);
		return jdbcTokenRepository;
	}

	// 创建AuthenticationSuccessHandler实现
	private AuthenticationSuccessHandler authenticationSuccessHandler() {
		return (request, response, authentication) -> {
			// 重定向到指定的URL
			response.sendRedirect("/");
		};
	}

	private AuthenticationFailureHandler authenticationFailureHandler() {
		return (request, response, authentication) -> {
			HttpSession session = request.getSession();
			session.setAttribute("loginFailure" , "true");
			// 重定向到指定的URL
			response.sendRedirect("/");
		};
	}

	public static void main(String[] args) {
		BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
		System.out.println(bCryptPasswordEncoder.encode("12345678"));
	}
}
